<template>
  <div
    class="h-full"
    :style="`padding: 0px; height: ${props.ganntHeight}; position: relative`"
  >
    <div style="width: 100%; height: 100%" ref="ganttContainer"></div>
    <el-dropdown
      ref="dropdown1"
      trigger="contextmenu"
      :style="`position: fixed; left: ${dropdown.x}px; top: ${dropdown.y}px`"
    >
      <span class="el-dropdown-link"> </span>
      <template #dropdown>
        <el-dropdown-menu v-if="dropdown.type == 3">
          <el-dropdown-item @click="addTask(1)">工作方向</el-dropdown-item>
          <el-dropdown-item @click="addTask(2, dropdown.id)"
            >工作要求</el-dropdown-item
          >
          <el-dropdown-item @click="addTask(3, dropdown.id)"
            >工作任务</el-dropdown-item
          >
        </el-dropdown-menu>
        <el-dropdown-menu v-if="dropdown.type == 0">
          <el-dropdown-item @click="addTask(2, dropdown.id)"
            >工作要求</el-dropdown-item
          >
          <el-dropdown-item @click="addTask(3, dropdown.id)"
            >工作任务</el-dropdown-item
          >
        </el-dropdown-menu>
      </template>
    </el-dropdown>

    <!-- 添加工作方向 -->
    <add-work-direction
      :visible="directionDialog.visible"
      :title="directionDialog.title"
      :data="directionDialog.data"
      @reset-table="getGanntList(props.searchQuery, true)"
      @change-visible="changeVisible"
    />

    <!-- 添加工作要求 -->
    <add-work-requirement
      :parentTaskId="requireDialog.parentTaskId"
      :visible="requireDialog.visible"
      :title="requireDialog.title"
      :data="requireDialog.data"
      @reset-table="getGanntList(props.searchQuery, true)"
      @change-visible="changeVisible"
    />

    <!-- 添加工作任务 -->
    <add-work-task
      :parentTaskId="taskDialog.parentTaskId"
      :visible="taskDialog.visible"
      :title="taskDialog.title"
      :data="taskDialog.data"
      @reset-table="getGanntList(props.searchQuery, true)"
      @change-visible="changeVisible"
    />

    <el-dialog
      :close-on-click-modal="false"
      v-model="deleteDialogVisible"
      title="提示"
      align-center
      width="500"
      class="deleteDialog"
    >
      <span>确认是否删除该任务?</span>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="deleteDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="deleteTask"> 确认 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="workgannt">
import { gantt, Task } from "dhtmlx-gantt";
import { useGantt } from "@/utils/useGantt";
import {
  taskManageColumns,
  taskExecutionColumns,
  taskProgressColumns,
} from "@/assets/js/mock";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import dayjs from "dayjs";
import type { DropdownInstance } from "element-plus";
import request from "@/utils/request";
import { ElMessage } from "element-plus";
import { useRoute } from "vue-router";
import router from "@/router";

const route = useRoute();
// import "dhtmlx-gantt/codebase/skins/dhtmlxgantt_material.css";

const props = defineProps({
  // 甘特图数据查询条件
  searchQuery: {
    type: Object,
    default: () => {
      return {};
    },
  },
  // 甘特图高度
  ganntHeight: {
    type: String,
    default: "600px",
  },
  // 甘特图类型：管理manage/执行execution/进度progress
  ganntType: {
    type: String,
    default: "manage",
  },
  // 时间切换
  unitTime1: {
    type: String,
    default: "year",
  },
});

const deleteDialogVisible = ref(false);
const deleteTaskId = ref();

// 表格操作 Hooks
const dropdown1 = ref<DropdownInstance>();
const dropdown = reactive({
  x: 0,
  y: 0,
  type: 4,
  id: "",
});

function addTemplate(x: number, y: number, type: number, id?: any) {
  dropdown.x = x;
  dropdown.y = y;
  dropdown.type = type;
  dropdown.id = id ?? "";
  if (!dropdown1.value) return;
  dropdown1.value.handleOpen();
}

const handleScroll = () => {
  // 处理滚轮事件的逻辑
  dropdown1.value?.handleClose();
};

const {
  radioSwitchChange,
  initGanttFunction,
  initEmptyState,
  tasks,
  columns,
  scaleTime,
  // dateScale,
  unitTime,
}: any = useGantt();

// 挂载ref
const ganttContainer = ref();

const workManageList: any = ref([]);
async function getGanntList(query: any, isUpdata?: boolean) {
  if (query === null) {
    // 详情组件查询
    const { data } = await request({
      url: `/system/oakeyworktask/sons/${route.query?.id}`,
      method: "post",
    });
    workManageList.value = data;
  } else {
    const { data } = await request({
      url:
        props.ganntType === "execution"
          ? `/system/oakeyworktask/performance`
          : `/system/oakeyworktask/tree`,
      method: "post",
      data: query,
    });
    workManageList.value = data;
  }

  initDataRender(isUpdata);
}

function deleteTask() {
  request({
    url: `/system/oakeyworktask/delete/${deleteTaskId.value}`,
    method: "post",
    data: {},
  })
    .then(() => {
      deleteTaskId.value = "";
      deleteDialogVisible.value = false;
      ElMessage.success("删除成功");
      getGanntList(props.searchQuery, true);
    })
    .catch(() => {
      deleteTaskId.value = "";
      deleteDialogVisible.value = false;
    });
}

function initDataRender(isUpdata?: boolean) {
  // 获取ids
  let ids: any[] = [];
  workManageList.value?.map((e) => {
    ids.push(e.id);
  });
  const arr: any = { data: [], links: [] };
  workManageList.value?.map((e: any) => {
    let plansText = "";
    if (e.taskType === "2") {
      e.grossProfits?.map((item: any) => {
        plansText +=
          item.indexName + item.planIndexValue + item.indexUnit + "、";
      });
    }

    arr.data.push({
      ...e,
      parent: ids.indexOf(e?.parent) === -1 ? "0" : e?.parent,
      progress: e?.completionDegree / 100 || 0,
      planStartDate: e?.planStartDate.split(" ")[0],
      planEndDate: e?.planEndDate.split(" ")[0],
      start_date: new Date(e?.planStartDate.split(" ")[0]),
      end_date: new Date(e?.planEndDate.split(" ")[0]),
      plansText: plansText.length
        ? plansText.substring(0, plansText.length - 1)
        : "",
    });
  });
  tasks.value = JSON.parse(JSON.stringify(arr));
  unitTime.value = scaleTime.value; // 切换日月周季
  if (isUpdata) {
    gantt.clearAll();
    gantt.parse(tasks.value);
    const today = new Date();
    gantt.addMarker({
      start_date: today,
      css: "today",
      text: "Today",
    });
    gantt.render();
  } else {
    initParam();
  }
}

function addTask(type: number, id?: string) {
  if (type === 1) {
    openDirectionDialog(true);
  } else if (type === 2) {
    openRequireDialog(true, id);
  } else {
    openTaskDialog(true, id);
  }
}

const myEvent: any = ref();

const initParam = () => {
  // 设置数据为空时文字显示
  initEmptyState();
  // 设置默认配置
  initGanttFunction();
  // 自定义配置（进度条、提示框、灯箱）
  templatesCustom();
  // tooltip提示文字设置
  tooltipCustom();
  // 表格列赋值
  gantt.config.drag_links = false;
  gantt.config.work_time = false;
  gantt.config.columns = columns.value;
  gantt.config.server_utc = false;
  gantt.config.auto_scheduling = true;
  // 设置全局配置
  gantt.config.summary = false; // 确保不启用总结模式
  // 默认是否展开树结构
  gantt.config.open_tree_initially = false;
  // 如果时间跨度很长，则使用此配置可用于显著加快图表显示速度。
  gantt.config.smart_scales = true;
  gantt.ignore_time = function () {
    return true;
  };
  gantt.config.details_on_dblclick = false;
  gantt.config.drag_progress = false;

  gantt.templates.grid_header_class = function (columnName, column) {
    if (columnName === "addTask") {
      return `bgadd`;
    }
    return "";
  };

  const gridHeaderClick = gantt.attachEvent(
    "onGridHeaderClick",
    function (name, e) {
      if (name === "addTask") {
        addTemplate(e.clientX, e.clientY, 3);
      }
      return true;
    }
  );

  const beforeTaskUpdate = gantt.attachEvent(
    "onBeforeTaskUpdate",
    function (id, newTask) {
      newTask.start_date = new Date(newTask.planStartDate);
      newTask.end_date = new Date(newTask.planEndDate);
      newTask.$no_end = false;
      newTask.$no_start = false;
      return;
      // 强制报错，终结project时间组合，Auto Scheduling属性需要付费
      // gantt.setTaskDate();
    }
  );

  //甘特图 点击事件
  const taskClick = gantt.attachEvent(
    "onTaskClick",
    async function (id: number, e: any) {
      // 点击新增按钮
      const buttonAdd = e.target.closest("[data-add]");
      if (buttonAdd) {
        const obj = tasks.value?.data.find((e: any) => e.id === id);
        if (obj?.taskType === "2" || obj?.taskType === "1") {
          openTaskDialog(true, id);
        } else {
          addTemplate(e.clientX, e.clientY, obj?.taskType, id);
        }
      }
      // 点击编辑按钮
      const buttonEdit = e.target.closest("[data-edit]");
      if (buttonEdit) {
        const data: any = await getTaskDetail(id);
        if (data.taskType == 0) {
          directionDialog.data = data;
          openDirectionDialog(true, { id: id });
        } else if (data.taskType == 1) {
          requireDialog.data = data;
          openRequireDialog(true, data.parentTaskId, { id: id });
        } else {
          taskDialog.data = data;
          openTaskDialog(true, data.parentTaskId, { id: id });
        }
      }

      // 点击查看按钮
      const buttonDetail = e.target.closest("[data-detail]");
      if (buttonDetail) {
        const data: any = await getTaskDetail(id);
        if (data.taskType == 0) {
          directionDialog.data = data;
          openDirectionDialog(false, { id: id });
        } else if (data.taskType == 1) {
          requireDialog.data = data;
          openRequireDialog(false, data.parentTaskId, { id: id });
        } else {
          taskDialog.data = data;
          openTaskDialog(false, data.parentTaskId, { id: id });
        }
      }

      //点击删除按钮
      const buttonDelete = e.target.closest("[data-delete]");
      if (buttonDelete) {
        deleteTaskId.value = id;
        deleteDialogVisible.value = true;
      }
      //点击taskName
      const buttonTitle = e.target.closest("[data-title]");
      // 状态为进度查询，且有子集的情况下，可以下钻
      if (buttonTitle && props.ganntType === "progress") {
        const obj: any = await getTaskDetail(id);
        if (obj.ishaveSon) {
          router.push({
            name: "KEYWORKWORKTASKDETAIL",
            query: { id },
          });
        }
      }

      // 点击执行按钮
      const buttonExecute = e.target.closest("[data-execute]");
      if (buttonExecute) {
        const data: any = await getTaskDetail(id);
        if (data.taskType == 1) {
          // router.push({
          //   name: "KEYWORKWORKEXECUTIONSETTINGREQUIREMENT",
          //   query: { id: id },
          // });
        } else {
          // router.push({
          //   name: "KEYWORKWORKEXECUTIONSETTINGTASKMENT",
          //   query: { id: id },
          // });
        }
      }
      return true;
    }
  );

  myEvent.value = [gridHeaderClick, beforeTaskUpdate, taskClick];

  // 初始化甘特图
  gantt.init(ganttContainer.value);

  // 渲染数据
  gantt.parse(tasks.value);

  const today = new Date();
  gantt.addMarker({
    start_date: today,
    css: "today",
    text: "今天",
  });

  // 现在，当你创建或编辑任务时，时间轴不会受到子任务的影响
  // gantt.refreshData();
};

// 进度条自定义
function templatesCustom() {
  // 自定义时间轴上的柱子文本
  gantt.templates.task_text = function (start, end, task: Task) {
    if (task?.$split_subtask) {
      return task.id.toString();
    } else {
      return `<span class='progress_value'>${
        Math.round(task.completionDegree ?? 0) + "%"
      }</span>`;
    }
  };

  // 自定义任务进度条颜色
  gantt.templates.task_class = function (start, end, task: Task) {
    if (task.workStatus === "2") {
      return "green";
    } else if (
      task.workStatus !== "2" &&
      dayjs(task.planEndDate).isBefore(dayjs())
    ) {
      return "red";
    } else if (
      task.workStatus === "1" &&
      !dayjs(task.planEndDate).isBefore(dayjs())
    ) {
      return "blue";
    }
    return "grey";
  };
}

// tooltip提示文字设置
function tooltipCustom() {
  gantt.templates.tooltip_text = function (start, end, task) {
    const parentName = !task.parent
      ? ""
      : tasks.value.data.filter((item: any) => item.id == task.parent)[0]
          ?.taskName;
    return `<p class="tooltip_p c-[#313c52]! text-[13px]">${task.seq}：${
      task.taskName
    }</p>
          <p><span class="mr-[20px] dblock">${
            task.leaderName ? `<b>负责人：</b>${task.leaderName}</span>` : ``
          }<span class="mr-[20px] dblock"><b>完成度：</b>${Math.round(
      task.completionDegree ?? 0
    )}%</span><b>工时：</b>${task.duration}天</p>
              <p><b>周期: </b>${gantt.templates.tooltip_date_format(
                start
              )} 至 ${gantt.templates.tooltip_date_format(end)}</p>
        ${
          task.createdUserName
            ? `<p><b>创建人：</b>${task.createdUserName}<b class="ml-[20px]">创建时间：</b>${task.createTime}</p>`
            : ``
        }
        ${parentName ? `<p><b>所属任务：</b>${parentName}</p>` : ``}
        ${task.plansText ? `<p><b>量化指标：</b>${task.plansText}</p>` : ``}
        `;
  };
}

/** 打开工作方向表单弹窗 */
const directionDialog = reactive<DialogOption>({
  visible: false,
  title: "",
  data: {},
});

async function getTaskDetail(id: string | number) {
  const { data } = await request({
    url: `/system/oakeyworktask/get/${id}`,
    method: "get",
  });
  return data;
}

function openDirectionDialog(canEdit: boolean, roleObj?: any) {
  directionDialog.visible = true;
  if (!canEdit) {
    directionDialog.title = `查看工作方向`;
  } else {
    if (roleObj) {
      directionDialog.title = `编辑工作方向`;
    } else {
      directionDialog.data = {};
      directionDialog.title = "新增工作方向";
    }
  }
}

/** 打开工作要求表单弹窗 */
const requireDialog = reactive<DialogOption>({
  parentTaskId: "",
  visible: false,
  title: "",
  data: {},
});

function openRequireDialog(canEdit: boolean, id: any, roleObj?: any) {
  requireDialog.visible = true;
  requireDialog.parentTaskId = id;
  if (!canEdit) {
    requireDialog.title = `查看工作要求`;
  } else {
    if (roleObj) {
      requireDialog.title = `编辑工作要求`;
    } else {
      requireDialog.data = {};
      requireDialog.title = "新增工作要求";
    }
  }
}

/** 打开工作任务表单弹窗 */
const taskDialog = reactive<DialogOption>({
  parentTaskId: "",
  visible: false,
  title: "",
  data: {},
});

function openTaskDialog(canEdit: boolean, id: any, roleObj?: any) {
  taskDialog.visible = true;
  taskDialog.parentTaskId = id;
  if (!canEdit) {
    taskDialog.title = `查看工作任务`;
  } else {
    if (roleObj) {
      taskDialog.title = `编辑工作任务`;
    } else {
      taskDialog.data = {};
      taskDialog.title = "新增工作任务";
    }
  }
}

function changeVisible(value: boolean) {
  directionDialog.visible = value;
  requireDialog.visible = value;
  taskDialog.visible = value;
}

watch(
  () => scaleTime.value,
  () => {
    radioSwitchChange(scaleTime.value);
  },
  {
    immediate: true,
  }
);

watch(
  () => props.unitTime1,
  () => {
    radioSwitchChange(props.unitTime1);
  },
  {
    immediate: true,
  }
);

onMounted(() => {
  scaleTime.value = "year";
  columns.value =
    props.ganntType === "manage"
      ? taskManageColumns
      : props.ganntType === "execution"
      ? taskExecutionColumns
      : taskProgressColumns;
  window.addEventListener("wheel", handleScroll);
});

onBeforeUnmount(() => {
  gantt.clearAll();
  window.removeEventListener("wheel", handleScroll);
  myEvent.value?.forEach((ele) => {
    gantt.detachEvent(ele);
  });
  // gantt.detachEvent(myEvent.value);
});

defineExpose({
  getGanntList,
  openDirectionDialog,
  openRequireDialog,
  openTaskDialog,
});
</script>
<style lang="scss">
@import url(@/styles/gantt.scss);
.bgadd {
  background-image: url(@/assets/images/add.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: auto;
  cursor: pointer;
}
.deleteDialog {
  .el-dialog__header {
    padding-bottom: 20px;
    border-bottom: none;
  }
  .el-dialog__body {
    padding: 0 20px;
  }
}
</style>
